package com.sright.bcard.content.biz.manager.strategy.impl;

import com.sright.bcard.common.service.share.dto.content.*;
import com.sright.bcard.common.service.share.utils.DataConvertUtils;
import com.sright.bcard.content.biz.manager.strategy.Strategy;
import com.sright.bcard.content.dal.dao.*;
import com.sright.bcard.content.dal.entity.*;
import com.sright.bcard.enterprise.dal.dao.AddressDAO;
import com.sright.bcard.enterprise.dal.dao.CompanyDAO;
import com.sright.bcard.enterprise.dal.dao.EnterpriseDAO;
import com.sright.bcard.enterprise.dal.entity.AddressDO;
import com.sright.bcard.enterprise.dal.entity.CompanyDO;
import com.sright.bcard.enterprise.dal.entity.EnterpriseDO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 名片信息全量查询策略
 */
@Component
@Slf4j
public class CardFullStrategy implements Strategy {

    @Autowired
    private CardDAO cardDAO;

    @Autowired
    private CardBaseInfoDAO cardBaseInfoDAO;

    @Autowired
    private CardSettingDAO cardSettingDAO;

    @Autowired
    private CardUserInfoDAO cardUserInfoDAO;

    @Autowired
    private CardUserCompanyInfoDAO cardUserCompanyInfoDAO;

    @Autowired
    private CompanyDAO companyDAO;

    @Autowired
    private EnterpriseDAO enterpriseDAO;

    @Autowired
    private AddressDAO addressDAO;

    @Autowired
    private TemplateDAO templateDAO;

    @Autowired
    private MaterialDAO materialDAO;

    @Override
    public CardFullDTO strategyInterface(CardDTO cardDTO) {
        // 根据cardId查询名片主体信息
        CardDO cardDO = cardDAO.selectByUserId(cardDTO.getUserId());
        if(cardDO == null) {
            return new CardFullDTO();
        }
        // 名片全量DTO
        CardFullDTO cardFullDTO = new CardFullDTO();
        log.info("CardFullStrategy.cardDTO.id : {}", cardDTO.getId());

        // 如果企业id为0 则是个人名片详情 否则是企业名片详情
        if(cardDO.getEnterpriseId() == 0) {
            buildPersonalCard(cardFullDTO, cardDO);
        } else {
            buildEnterpriseCard(cardFullDTO, cardDO);
        }
        return cardFullDTO;
    }

    /**
     * 构建企业名片信息
     * @param cardFullDTO
     * @param cardDO
     */
    private void buildEnterpriseCard(CardFullDTO cardFullDTO, CardDO cardDO) {
        buildCommonInfo(cardFullDTO, cardDO);
        buildCardUserCompanyInfo(cardFullDTO, cardDO);
        buildMeterialInfo(cardFullDTO, cardDO);
    }

    /**
     * 构建个人名片信息
     * @param cardFullDTO
     * @param cardDO
     */
    private void buildPersonalCard(CardFullDTO cardFullDTO, CardDO cardDO) {
        buildCommonInfo(cardFullDTO, cardDO);
        buildMeterialInfo(cardFullDTO, cardDO);
    }

    /**
     * 构建公共基础信息
     * @param cardFullDTO
     * @param cardDO
     */
    private void buildCommonInfo(CardFullDTO cardFullDTO, CardDO cardDO) {
        CardInfoDTO cardInfoDTO = new CardInfoDTO();
        // 名片主体信息
        CardDTO targetCardDTO = new CardDTO();
        // 名片基础信息
        CardBaseInfoDTO cardBaseInfoDTO = new CardBaseInfoDTO();
        // 卡片设置信息
        CardSettingDTO cardSettingDTO = new CardSettingDTO();
        // 名片用户基础信息
        List<CardUserInfoDTO> cardUserInfoDTOList = new ArrayList<>();
        // DO转DTO
        DataConvertUtils.convertDO2DTO(cardDO, targetCardDTO);
        // 根据baseInfoId查询CardBaseInfoDO
        CardBaseInfoDO cardBaseInfoDO = cardBaseInfoDAO.selectById(cardDO.getBaseInfoId());
        // DO转DTO
        DataConvertUtils.convertDO2DTO(cardBaseInfoDO, cardBaseInfoDTO);
        // 根据userId查询CardSetting
        CardSettingDO cardSettingDO = cardSettingDAO.selectByUserId(cardDO.getUserId());
        // DO 转DTO
        DataConvertUtils.convertDO2DTO(cardSettingDO, cardSettingDTO);
        // 根据userId查询用户基础信息
        List<CardUserInfoDO> cardUserInfoDOList = cardUserInfoDAO.selectByUserId(cardDO.getUserId());
        DataConvertUtils.convertDOList2DTOList(cardUserInfoDOList, cardUserInfoDTOList, CardUserInfoDTO.class);
        cardInfoDTO.setCardInfo(targetCardDTO == null ? new CardDTO() : targetCardDTO);
        cardInfoDTO.setCardBaseInfo(cardBaseInfoDTO == null ? new CardBaseInfoDTO() : cardBaseInfoDTO);
        cardInfoDTO.setCardSettingInfo(cardSettingDTO == null ? new CardSettingDTO() : cardSettingDTO);
        cardInfoDTO.setCardUserInfoList(CollectionUtils.isEmpty(cardUserInfoDTOList) ? new ArrayList<CardUserInfoDTO>() : cardUserInfoDTOList);
        cardFullDTO.setCardInfo(cardInfoDTO == null ? new CardInfoDTO() : cardInfoDTO);
    }

    /**
     * 构建企业相关信息
     * @param cardFullDTO
     * @param cardDO
     */
    private void buildCardUserCompanyInfo(CardFullDTO cardFullDTO, CardDO cardDO) {
        CardEnterpriseDTO cardEnterpriseDTO = new CardEnterpriseDTO();
        // 名片用户企业信息
        List<CardUserCompanyInfoDTO> cardUserCompanyInfoDTOList = new ArrayList<>();
        // 用户公司信息
        List<CompanyDTO> companyDTOList = new ArrayList<>();
        // 用户基础信息
        List<EnterpriseDTO> enterpriseDTOList = new ArrayList<>();
        // 用户企业地址信息
        List<AddressDTO> addressDTOList = new ArrayList<>();
        List<CardUserInfoDO> cardUserInfoDOList = cardUserInfoDAO.selectByUserId(cardDO.getUserId());
        // cardInfoUserId列表
        List<Long> cardUserInfoIdList = cardUserInfoDOList.stream().
                map(CardUserInfoDO::getId).collect(Collectors.toList());
        List<CardUserCompanyInfoDO> cardUserCompanyInfoDOList = cardUserCompanyInfoDAO.selectByCardUserInfoIds(cardUserInfoIdList);
        DataConvertUtils.convertDOList2DTOList(cardUserCompanyInfoDOList, cardUserCompanyInfoDTOList, CardUserCompanyInfoDO.class);
        // companyId列表
        List<Long> companyIdList = cardUserCompanyInfoDOList.stream().map(CardUserCompanyInfoDO::getCompanyId).collect(Collectors.toList());
        List<CompanyDO> companyDOList = companyDAO.selectByCompanyIdList(companyIdList);
        // DO转DTO
        DataConvertUtils.convertDOList2DTOList(companyDOList, companyDTOList, CompanyDTO.class);
        // 获取企业id列表
        List<Long> enterpriseIdList = companyDOList.stream().map(CompanyDO::getEnterpriseId).collect(Collectors.toList());
        List<EnterpriseDO> enterpriseDOList = enterpriseDAO.selectByEnterpriseIdList(enterpriseIdList);
        // DO转DTO
        DataConvertUtils.convertDOList2DTOList(enterpriseDOList, enterpriseDTOList, EnterpriseDTO.class);
        List<AddressDO> addressDOList = addressDAO.selectByEnterpriseIdList(enterpriseIdList);
        // DO 转 DTO
        DataConvertUtils.convertDOList2DTOList(addressDOList, addressDTOList, AddressDTO.class);
        cardEnterpriseDTO.setCompanyListInfo(CollectionUtils.isEmpty(companyDTOList) ? new ArrayList<CompanyDTO>() : companyDTOList);
        cardEnterpriseDTO.setCardUserCompanyInfoList(CollectionUtils.isEmpty(cardUserCompanyInfoDTOList) ? new ArrayList<CardUserCompanyInfoDTO>() : cardUserCompanyInfoDTOList);
        cardEnterpriseDTO.setEnterpriseListInfo(CollectionUtils.isEmpty(enterpriseDTOList) ? new ArrayList<EnterpriseDTO>() : enterpriseDTOList);
        cardEnterpriseDTO.setAddressListInfo(CollectionUtils.isEmpty(addressDTOList) ? new ArrayList<AddressDTO>() : addressDTOList);
        cardFullDTO.setCardEnterpriseInfo(cardEnterpriseDTO == null ? new CardEnterpriseDTO() : cardEnterpriseDTO);
    }

    /**
     * 构建素材相关信息
     * @param cardFullDTO
     * @param cardDO
     */
    private void buildMeterialInfo(CardFullDTO cardFullDTO, CardDO cardDO) {
        // 名片模板素材DTO
        TemplateMaterialDTO templateMaterialDTO = new TemplateMaterialDTO();
        // 名片模板信息
        CardTemplateDTO templateDTO = new CardTemplateDTO();
        // 名片素材列表
        List<MaterialDTO> materialDTOS = new ArrayList<>();
        CardBaseInfoDO cardBaseInfoDO = cardBaseInfoDAO.selectById(cardDO.getBaseInfoId());
        // 模板id
        Long templateId = cardBaseInfoDO.getTemplateId();
        // 素材ids
        String materialIds = cardBaseInfoDO.getMaterialIds();
        List<Long> materialIdList = new ArrayList<>();
        Arrays.asList(materialIds.split(",")).forEach(materialId -> materialIdList.add(Long.parseLong(materialIds)));
        TemplateDO templateDO = templateDAO.selectById(templateId);
        // DO 转 DTO
        DataConvertUtils.convertDO2DTO(templateDO, templateDTO);
        List<MaterialDO> materialDOList = materialDAO.selectByMaterialIdList(materialIdList);
        // DO 转 DTO
        DataConvertUtils.convertDOList2DTOList(materialDOList, materialDTOS, MaterialDTO.class);
        templateMaterialDTO.setTemplateDTO(templateDTO == null ? new CardTemplateDTO() : null);
        templateMaterialDTO.setMaterialDTOS(CollectionUtils.isEmpty(materialDTOS) ? new ArrayList<MaterialDTO>() : materialDTOS);
        cardFullDTO.setTemplateMaterialInfo(templateMaterialDTO == null ? new TemplateMaterialDTO() : templateMaterialDTO);
    }
}
